From c61956c59285fdd959d8ed120a7fe1f1383442ac Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 22 Mar 2013 20:30:51 -0400 Subject: [PATCH] wayland: Implement cursor theme changing Add gdk_wayland_display_set_cursor_theme and implement it. --- gdk/wayland/gdkcursor-wayland.c | 59 ++++++++++++++++++++------------ gdk/wayland/gdkdisplay-wayland.c | 36 +++++++++++++++---- gdk/wayland/gdkprivate-wayland.h | 2 ++ gdk/wayland/gdkwaylanddisplay.h | 3 ++ 4 files changed, 72 insertions(+), 28 deletions(-) diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index a8df766916..b705b8fdc4 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -128,6 +128,41 @@ _gdk_wayland_display_finalize_cursors (GdkWaylandDisplay *display) g_slist_free (display->cursor_cache); } +static gboolean +set_cursor_from_theme (GdkWaylandCursor *cursor, struct wl_cursor_theme *theme) +{ + struct wl_cursor *c; + + c = wl_cursor_theme_get_cursor (theme, cursor->name); + if (!c) + { + g_warning (G_STRLOC ": Unable to load %s from the cursor theme", cursor->name); + + /* return the left_ptr cursor as a fallback */ + c = wl_cursor_theme_get_cursor (theme, "left_ptr"); + + if (!c) + return FALSE; + } + + cursor->hotspot_x = c->images[0]->hotspot_x; + cursor->hotspot_y = c->images[0]->hotspot_y; + cursor->width = c->images[0]->width; + cursor->height = c->images[0]->height; + + cursor->buffer = wl_cursor_image_get_buffer(c->images[0]); + cursor->free_buffer = FALSE; + + return TRUE; +} + +void +_gdk_wayland_display_update_cursors (GdkWaylandDisplay *display, + struct wl_cursor_theme *theme) +{ + g_slist_foreach (display->cursor_cache, (GFunc) set_cursor_from_theme, theme); +} + static void gdk_wayland_cursor_finalize (GObject *object) { @@ -286,33 +321,13 @@ _gdk_wayland_display_get_cursor_for_name (GdkDisplay *display, if (!name || g_str_equal (name, "blank_cursor")) return GDK_CURSOR (private); - cursor = wl_cursor_theme_get_cursor (wayland_display->cursor_theme, - name); - - if (!cursor) - { - g_warning (G_STRLOC ": Unable to load %s from the cursor theme", name); - - /* return the left_ptr cursor as a fallback */ - cursor = wl_cursor_theme_get_cursor (wayland_display->cursor_theme, - "left_ptr"); - - /* if the fallback failed to load, return a blank pointer */ - if (!cursor) - return GDK_CURSOR (private); - } + if (!set_cursor_from_theme (private, wayland_display->cursor_theme)) + return GDK_CURSOR (private); /* TODO: Do something clever so we can do animated cursors - move the * wl_pointer_set_cursor to a function here so that we can do the magic to * iterate through */ - private->hotspot_x = cursor->images[0]->hotspot_x; - private->hotspot_y = cursor->images[0]->hotspot_y; - private->width = cursor->images[0]->width; - private->height = cursor->images[0]->height; - - private->buffer = wl_cursor_image_get_buffer(cursor->images[0]); - private->free_buffer = FALSE; add_to_cache (wayland_display, private); diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index c3442f0361..5061f07a16 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -562,11 +562,36 @@ gdk_wayland_display_init (GdkWaylandDisplay *display) display->xkb_context = xkb_context_new (0); } +void +gdk_wayland_display_set_cursor_theme (GdkDisplay *display, + const gchar *name, + gint size) +{ + GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY(display); + struct wl_cursor_theme *theme; + + g_assert (wayland_display); + g_assert (wayland_display->shm); + + theme = wl_cursor_theme_load (name, size, wayland_display->shm); + if (theme == NULL) + { + g_warning ("Failed to load cursor theme %s\n", name); + return; + } + + _gdk_wayland_display_update_cursors (wayland_display, theme); + + if (wayland_display->cursor_theme != NULL) + wl_cursor_theme_destroy (wayland_display->cursor_theme); + wayland_display->cursor_theme = theme; +} + static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *wayland_display) { guint size; - const gchar *theme_name; + const gchar *name; GValue v = G_VALUE_INIT; g_assert (wayland_display); @@ -581,13 +606,12 @@ _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *wayland_display) g_value_init (&v, G_TYPE_STRING); if (gdk_setting_get ("gtk-cursor-theme-name", &v)) - theme_name = g_value_get_string (&v); + name = g_value_get_string (&v); else - theme_name = "default"; + name = "default"; - wayland_display->cursor_theme = wl_cursor_theme_load (theme_name, - size, - wayland_display->shm); + gdk_wayland_display_set_cursor_theme (GDK_DISPLAY (wayland_display), + name, size); g_value_unset (&v); } diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index efbc87e3f5..c083396e35 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -54,6 +54,8 @@ GdkKeymap *_gdk_wayland_keymap_new_from_fd (uint32_t format, struct xkb_state *_gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap); void _gdk_wayland_display_finalize_cursors (GdkWaylandDisplay *display); +void _gdk_wayland_display_update_cursors (GdkWaylandDisplay *display, + struct wl_cursor_theme *theme); GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, GdkCursorType cursor_type); diff --git a/gdk/wayland/gdkwaylanddisplay.h b/gdk/wayland/gdkwaylanddisplay.h index 336fff3709..1ec9964946 100644 --- a/gdk/wayland/gdkwaylanddisplay.h +++ b/gdk/wayland/gdkwaylanddisplay.h @@ -47,6 +47,9 @@ GType gdk_wayland_display_get_type (void); struct wl_display *gdk_wayland_display_get_wl_display (GdkDisplay *display); struct wl_compositor *gdk_wayland_display_get_wl_compositor (GdkDisplay *display); struct wl_shell *gdk_wayland_display_get_wl_shell (GdkDisplay *display); +void gdk_wayland_display_set_cursor_theme (GdkDisplay *display, + const gchar *theme, + gint size); G_END_DECLS -- 2.30.2